let Vue;

// 声明Store类
class Store {
  constructor(options) {
    const temp = {}
    for (const key in options.getters) {
      // temp[key] = () => {
      //   return options.getters[key](this.state)
      // }
      temp[key] = () => {
        return options.getters[key](this.state)
      }
    }
    this._vm = new Vue({
      //data中的值都会做响应化处理
      data: {
        $$state: options.state
      },
      computed:temp
    })
    
    // 保存mutations
    this._mutatios = options.mutations
    this._actions = options.actions
    this._getters = options.getters

    // 锁死commit,dispatch函数this指向
    const store = this
    const {commit,dispatch} = store
    this.commit = function boundCommit(type, payload) {
      commit.call(store, type, payload)
    }
    this.dispatch = function boundDispatch(type, payload) {
      dispatch.call(store, type, payload)
    }
    
  }

    // 暗号: first blood
  // 这道题我没通过computed的方法实现,因为不知道怎么将getters里面的state参数转化成Store类里面的state,就选择了返回执行后的函数这种方法
  get getters() {
    // let tempObj = {}
    // for (const key in this._getters) {
    //   tempObj[key] = this._getters[key](this.state)
    // }
    // return tempObj
    return this._vm
  }

  set getters(v) {
    console.error('不能这么直接赋值')
  }

  // 存取器是之成为只读
  get state() {
    return this._vm._data.$$state
  }

  set state(v) {
    console.error(' please use replaceState to reset state')
  }



    // Object.keys(options.getters).forEach(key => {
    //   temp[key] = function() {
    //     return options.getters[key](this.state)
    //   }
    // })

  // commit 修改状态
  commit(type, payload) {
    // 1.获取mutation
    const entry = this._mutatios[type]

    if(!entry) {
      console.error('大兄弟,没有这个mutation ')
      return
    }

    entry(this.state, payload);
  }

  // dispatch 异步任务或者复杂逻辑
  dispatch(type, payload) {
    // 1.获取action
    const entry = this._actions[type]

    if(!entry) {
      console.error('大兄弟,没有这个mutation ')
      return
    }

    entry(this, payload);
  }

}

// install方法
function install(_Vue) {
  Vue = _Vue

  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

//导出一个对象,作为Vuex
export default { Store, install };